package job

import (
	"fmt"
	"scheduler/dal"
	"time"

	log "github.com/omidnikta/logrus"
	//	"github.com/robfig/cron"
)

//固定时间任务
type Task struct {
	ID      string
	Retry   int //失败后重试次数，默认不重试
	Action  *Action
	StartAt time.Time

	stop   chan error
	retErr error
}

/*
失败并重试Retry次数后会把错误通过传回，
如果成功返回nil
*/

func (t *Task) RunFunc(f func(error)) {
	t.Run()
	f(t.retErr)
}

func (t *Task) Run() {
	log.Infof("taskId:%s begin,startAt:%s", t.ID, t.StartAt.String())
	to := Time2Duration(t.StartAt)

	select {
	case <-time.After(to):
		for i := 0; i < t.Retry+1; i++ {
			t.retErr = t.do()
			if nil == t.retErr {
				break
			}
		}
	case t.retErr = <-t.stop:
	}
	log.Infof("taskId:%s end,retErr:%s", t.ID, t.retErr)
}

func (t *Task) do() error {
	return t.Action.Do()
}

/*
只是关闭本次任务的进程，但没有彻底关闭任务，下次重启本服务，还会从数据库中取出此任务，开始继续执行
*/
func (t *Task) Stop(reason string) {
	var err error = nil
	if "" != reason {
		err = fmt.Errorf("%s", reason)
	}

	t.stop <- err
}

func (t *Task) Restart() {
	t.Stop("restart")
	t.reload()
	t.Run()
}

func (t *Task) RestartFunc(f func(error)) {
	t.Stop("restart")
	t.reload()
	t.RunFunc(f)
}

func (t *Task) reload() {
	task, err := dal.TaskModel().GetById(t.ID)
	if nil != err {
		log.Error(err)
		return
	}

	t.Retry = task.Retry
	t.Action.Addr = task.Addr
	t.Action.Path = task.Path
	t.Action.Body = task.Body
	t.StartAt = DurationToTime(time.Duration(task.StartAt))
}
